/*
 * @author hzq
 * @status done
 * @see 🚀 https://juejin.cn/post/7256302444388761661
 * @date 2025-02-01 17:40:27
 * @description 三维空间中的矩阵运算
 * @usage
 */

/**
 * 旋转矩阵
 * @param axis 旋转轴
 * @param angle 角度
 * @returns
 */
export function createRotationMatrix(axis: "x" | "y" | "z", angle: number) {
  const c = Math.cos(angle);
  const s = Math.sin(angle);
  let result: number[][] = [];
  switch (axis) {
    case "x":
      result = [
        [1, 0, 0, 0],
        [0, c, -s, 0],
        [0, s, c, 0],
        [0, 0, 0, 1],
      ];
      break;
    case "y":
      result = [
        [c, 0, s, 0],
        [0, 1, 0, 0],
        [-s, 0, c, 0],
        [0, 0, 0, 1],
      ];
      break;
    case "z":
      result = [
        [c, -s, 0, 0],
        [s, c, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1],
      ];
      break;
    default:
      throw new Error("Invalid axis");
  }
  return result;
}

/**
 * 平移矩阵
 * @param dx x轴平移
 * @param dy y轴平移
 * @param dz z轴平移
 * @returns
 */
export function createTranslationMatrix(dx: number, dy: number, dz: number) {
  return [
    [1, 0, 0, 0],
    [0, 1, 0, 0],
    [0, 0, 1, 0],
    [dx, dy, dz, 1],
  ];
}

/**
 * 缩放矩阵
 * @param sx x轴缩放
 * @param sy y轴缩放
 * @param sz z轴缩放
 * @returns
 */
export function createScaleMatrix(sx: number, sy: number, sz: number) {
  return [
    [sx, 0, 0, 0],
    [0, sy, 0, 0],
    [0, 0, sz, 0],
    [0, 0, 0, 1],
  ];
}

/**
 * 矩阵与向量乘法
 * @param matrix 矩阵
 * @param vector 向量
 * @returns
 */
export function multiplyMatrixVector(matrix: number[][], vector: number[]) {
  let result: number[] = [0, 0, 0, 0];
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      result[i] += matrix[i][j] * vector[j];
    }
  }
  return result;
}

/**
 * 透视投影矩阵
 * @param f 焦距
 * @returns
 */
export function createProjectionMatrix(f: number) {
  return [
    [f, 0, 0, 0],
    [0, f, 0, 0],
    [0, 0, 1, 0],
    [0, 0, 0, 1],
  ];
}
